package com.alipay.util;

import com.alipay.constants.Constants;
import com.alipay.exception.BusinessException;
import com.alipay.model.enums.ResponseCodeEnum;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

/**
 *
 * @author Jun
 * @date 2019/3/22
 */
@Slf4j
public class RedBagUtil {
    /**
     * 计算随机红包金额
     *  @param total 红包总金额
     *  @param num 红包个数
     * @return
     */
    public static List<BigDecimal> getRandomRedBag(BigDecimal total, int num) {
        List<BigDecimal> res = new ArrayList<>();
        Random random = new Random();
        BigDecimal min = Constants.RedBagSingleMin;
        if (num <= 0 || total.compareTo(min.multiply(BigDecimal.valueOf(num))) < 0) {
            log.error("random red bag cannot distribution, total={}, num ={}", total, num);
            throw new BusinessException(ResponseCodeEnum.ARG_ERROR);
        }
        BigDecimal totalTemp = total;
        BigDecimal totalFinal = BigDecimal.ZERO;
        int n = num + 1;
        while (n > 1) {
            BigDecimal max = totalTemp.divide(BigDecimal.valueOf(n), 2, RoundingMode.HALF_EVEN).multiply(BigDecimal.valueOf(2));
            BigDecimal money = BigDecimal.valueOf(random.nextDouble()).multiply(max);
            money = money.compareTo(min) < 0 ? min : money;
            money = money.multiply(BigDecimal.valueOf(100)).divide(BigDecimal.valueOf(100), 2, RoundingMode.HALF_EVEN);
            totalTemp = totalTemp.subtract(money);
            res.add(money);
            totalFinal = totalFinal.add(money);
            n--;
        }
        if (totalFinal.compareTo(total) > 0) {
            BigDecimal surplus = totalFinal.subtract(total);
            BigDecimal surplusTemp = BigDecimal.ZERO;
            int i = 0;
            while (surplus.compareTo(surplusTemp) != 0) {
                surplusTemp = surplusTemp.add(res.get(i).subtract(min));
                res.set(i, min);
                if (surplus.compareTo(surplusTemp) < 0) {
                    BigDecimal temp = surplusTemp.subtract(surplus);
                    res.set(i, res.get(i).add(temp));
                    surplusTemp = surplusTemp.subtract(temp);
                }
                i++;
            }
        } else if (totalFinal.compareTo(total) < 0) {
            res.set(0, res.get(0).add(total.subtract(totalFinal)));
        }
        Collections.shuffle(res);
        return res;
    }
}
